/*
 * 🔔 EBP3901蜂鸣器测试程序 - 完整测试版
 *
 * 开发板: Eswin EBP3901 (32位RISC-V)
 * 功能: 蜂鸣器全功能测试
 * 作者: AIOT项目组
 * 版本: v1.0
 *
 * 测试内容:
 * ✅ 基础蜂鸣器控制
 * ✅ 音调频率测试
 * ✅ 音乐播放测试
 * ✅ PWM控制测试
 * ✅ 按键交互测试
 *
 * 硬件连接:
 * 蜂鸣器正极 → EBP3901 GPIO42 (J12引脚32)
 * 蜂鸣器负极 → GND (J12引脚6)
 *
 * 可选: 通过NPN三极管驱动以增大音量
 * 三极管基极 → GPIO42
 * 三极管集电极 → 蜂鸣器正极
 * 三极管发射极 → GND
 * 蜂鸣器负极 → 5V (通过上拉电阻)
 */

// ========== 硬件配置 ==========
#define BUZZER_PIN 42 // EBP3901 J12引脚32 (GPIO42)
#define LED_PIN 2     // 板载LED (可选)
#define BUTTON_PIN 0  // 板载按键 (可选)

// ========== 音符频率定义 ==========
// 标准音符频率 (Hz)
#define NOTE_B0 31
#define NOTE_C1 33
#define NOTE_CS1 35
#define NOTE_D1 37
#define NOTE_DS1 39
#define NOTE_E1 41
#define NOTE_F1 44
#define NOTE_FS1 46
#define NOTE_G1 49
#define NOTE_GS1 52
#define NOTE_A1 55
#define NOTE_AS1 58
#define NOTE_B1 62
#define NOTE_C2 65
#define NOTE_CS2 69
#define NOTE_D2 73
#define NOTE_DS2 78
#define NOTE_E2 82
#define NOTE_F2 87
#define NOTE_FS2 93
#define NOTE_G2 98
#define NOTE_GS2 104
#define NOTE_A2 110
#define NOTE_AS2 117
#define NOTE_B2 123
#define NOTE_C3 131
#define NOTE_CS3 139
#define NOTE_D3 147
#define NOTE_DS3 156
#define NOTE_E3 165
#define NOTE_F3 175
#define NOTE_FS3 185
#define NOTE_G3 196
#define NOTE_GS3 208
#define NOTE_A3 220
#define NOTE_AS3 233
#define NOTE_B3 247
#define NOTE_C4 262
#define NOTE_CS4 277
#define NOTE_D4 294
#define NOTE_DS4 311
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_FS4 370
#define NOTE_G4 392
#define NOTE_GS4 415
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_CS5 554
#define NOTE_D5 587
#define NOTE_DS5 622
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_FS5 740
#define NOTE_G5 784
#define NOTE_GS5 831
#define NOTE_A5 880
#define NOTE_AS5 932
#define NOTE_B5 988
#define NOTE_C6 1047
#define NOTE_CS6 1109
#define NOTE_D6 1175
#define NOTE_DS6 1245
#define NOTE_E6 1319
#define NOTE_F6 1397
#define NOTE_FS6 1480
#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976
#define NOTE_C7 2093
#define NOTE_CS7 2217
#define NOTE_D7 2349
#define NOTE_DS7 2489
#define NOTE_E7 2637
#define NOTE_F7 2794
#define NOTE_FS7 2960
#define NOTE_G7 3136
#define NOTE_GS7 3322
#define NOTE_A7 3520
#define NOTE_AS7 3729
#define NOTE_B7 3951
#define NOTE_C8 4186
#define NOTE_CS8 4435
#define NOTE_D8 4699
#define NOTE_DS8 4978

// ========== 全局变量 ==========
int testMode = 0;           // 测试模式
unsigned long lastTest = 0; // 上次测试时间
bool ledState = false;      // LED状态
bool buttonPressed = false; // 按键状态

// ========== 初始化 ==========
void setup()
{
    // 串口初始化
    Serial.begin(115200);
    delay(1000);

    Serial.println("========================================");
    Serial.println("🔔 EBP3901蜂鸣器测试程序启动");
    Serial.println("========================================");
    Serial.println("开发板: Eswin EBP3901 (RISC-V)");
    Serial.println("GPIO配置: 蜂鸣器 → GPIO42");
    Serial.println("========================================");

    // 引脚初始化
    pinMode(BUZZER_PIN, OUTPUT);
    pinMode(LED_PIN, OUTPUT);
    pinMode(BUTTON_PIN, INPUT_PULLUP);

    // 初始状态
    digitalWrite(BUZZER_PIN, LOW);
    digitalWrite(LED_PIN, LOW);

    Serial.println("✅ 硬件初始化完成");

    // 启动测试音
    Serial.println("🎵 播放启动提示音...");
    playStartupSound();

    // 显示测试菜单
    showTestMenu();
}

// ========== 主循环 ==========
void loop()
{
    // 检查串口命令
    if (Serial.available())
    {
        String command = Serial.readStringUntil('\n');
        command.trim();
        processCommand(command);
    }

    // 检查按键
    checkButton();

    // 自动循环测试 (每10秒)
    if (millis() - lastTest >= 10000)
    {
        autoTest();
        lastTest = millis();
    }

    delay(50);
}

// ========== 命令处理 ==========
void processCommand(String cmd)
{
    Serial.println("📝 收到命令: " + cmd);

    if (cmd == "1")
    {
        test1_BasicBeep();
    }
    else if (cmd == "2")
    {
        test2_FrequencyTest();
    }
    else if (cmd == "3")
    {
        test3_MusicTest();
    }
    else if (cmd == "4")
    {
        test4_PWMTest();
    }
    else if (cmd == "5")
    {
        test5_InteractiveTest();
    }
    else if (cmd == "6")
    {
        test6_ContinuousTest();
    }
    else if (cmd == "menu" || cmd == "m")
    {
        showTestMenu();
    }
    else if (cmd == "stop" || cmd == "s")
    {
        stopBuzzer();
        Serial.println("🔇 蜂鸣器已停止");
    }
    else
    {
        Serial.println("❌ 无效命令，输入 'menu' 查看菜单");
    }
}

// ========== 测试菜单 ==========
void showTestMenu()
{
    Serial.println("\n========================================");
    Serial.println("🎯 EBP3901蜂鸣器测试菜单");
    Serial.println("========================================");
    Serial.println("1 - 基础蜂鸣测试");
    Serial.println("2 - 频率扫描测试");
    Serial.println("3 - 音乐播放测试");
    Serial.println("4 - PWM调制测试");
    Serial.println("5 - 交互式测试");
    Serial.println("6 - 连续测试模式");
    Serial.println("----------------------------------------");
    Serial.println("输入命令: menu(菜单) stop(停止)");
    Serial.println("========================================");
}

// ========== 测试1: 基础蜂鸣 ==========
void test1_BasicBeep()
{
    Serial.println("\n🔔 测试1: 基础蜂鸣测试");
    Serial.println("----------------------------------------");

    // 简单蜂鸣
    Serial.println("📢 短蜂鸣 x3");
    for (int i = 0; i < 3; i++)
    {
        digitalWrite(BUZZER_PIN, HIGH);
        delay(200);
        digitalWrite(BUZZER_PIN, LOW);
        delay(200);
        Serial.print(".");
    }
    Serial.println(" 完成");

    delay(1000);

    // 长蜂鸣
    Serial.println("📢 长蜂鸣 x2");
    for (int i = 0; i < 2; i++)
    {
        digitalWrite(BUZZER_PIN, HIGH);
        delay(800);
        digitalWrite(BUZZER_PIN, LOW);
        delay(300);
        Serial.print(".");
    }
    Serial.println(" 完成");

    Serial.println("✅ 基础蜂鸣测试完成");
}

// ========== 测试2: 频率测试 ==========
void test2_FrequencyTest()
{
    Serial.println("\n🎵 测试2: 频率扫描测试");
    Serial.println("----------------------------------------");

    int frequencies[] = {100, 200, 500, 1000, 1500, 2000, 3000, 4000};
    int numFreq = sizeof(frequencies) / sizeof(frequencies[0]);

    Serial.println("🔊 播放不同频率:");
    for (int i = 0; i < numFreq; i++)
    {
        Serial.print("频率: ");
        Serial.print(frequencies[i]);
        Serial.println(" Hz");

        tone(BUZZER_PIN, frequencies[i], 500);
        delay(700);
    }

    Serial.println("🌊 频率扫描 (100Hz - 3000Hz):");
    for (int freq = 100; freq <= 3000; freq += 100)
    {
        tone(BUZZER_PIN, freq, 100);
        delay(120);
        if (freq % 500 == 0)
        {
            Serial.print(freq);
            Serial.print("Hz ");
        }
    }
    Serial.println("\n✅ 频率测试完成");
}

// ========== 测试3: 音乐测试 ==========
void test3_MusicTest()
{
    Serial.println("\n🎼 测试3: 音乐播放测试");
    Serial.println("----------------------------------------");

    // 生日快乐歌
    Serial.println("🎵 播放: 生日快乐");
    playHappyBirthday();

    delay(1000);

    // 超级马里奥主题
    Serial.println("🎵 播放: 超级马里奥主题");
    playMarioTheme();

    Serial.println("✅ 音乐测试完成");
}

// ========== 测试4: PWM测试 ==========
void test4_PWMTest()
{
    Serial.println("\n⚡ 测试4: PWM调制测试");
    Serial.println("----------------------------------------");

    // PWM频率测试
    Serial.println("🔊 PWM音量控制测试:");

    for (int duty = 10; duty <= 255; duty += 30)
    {
        Serial.print("PWM占空比: ");
        Serial.print((duty * 100) / 255);
        Serial.println("%");

        // 使用analogWrite产生PWM信号
        for (int i = 0; i < 20; i++)
        {
            analogWrite(BUZZER_PIN, duty);
            delayMicroseconds(1000);
            analogWrite(BUZZER_PIN, 0);
            delayMicroseconds(1000);
        }
        delay(500);
    }

    analogWrite(BUZZER_PIN, 0);
    Serial.println("✅ PWM测试完成");
}

// ========== 测试5: 交互式测试 ==========
void test5_InteractiveTest()
{
    Serial.println("\n🎮 测试5: 交互式测试");
    Serial.println("----------------------------------------");
    Serial.println("按板载按键听不同音效 (10秒测试)");

    unsigned long startTime = millis();
    int soundIndex = 0;

    while (millis() - startTime < 10000)
    {
        if (digitalRead(BUTTON_PIN) == LOW && !buttonPressed)
        {
            buttonPressed = true;

            // 播放不同音效
            switch (soundIndex % 4)
            {
            case 0:
                playBeepPattern1();
                Serial.println("🔔 音效1");
                break;
            case 1:
                playBeepPattern2();
                Serial.println("🔔 音效2");
                break;
            case 2:
                playBeepPattern3();
                Serial.println("🔔 音效3");
                break;
            case 3:
                playBeepPattern4();
                Serial.println("🔔 音效4");
                break;
            }
            soundIndex++;
        }
        else if (digitalRead(BUTTON_PIN) == HIGH)
        {
            buttonPressed = false;
        }

        delay(50);
    }

    Serial.println("✅ 交互式测试完成");
}

// ========== 测试6: 连续测试 ==========
void test6_ContinuousTest()
{
    Serial.println("\n🔄 测试6: 连续测试模式");
    Serial.println("----------------------------------------");
    Serial.println("连续播放各种音效 (输入 'stop' 停止)");

    int pattern = 0;

    while (true)
    {
        // 检查停止命令
        if (Serial.available())
        {
            String cmd = Serial.readStringUntil('\n');
            cmd.trim();
            if (cmd == "stop" || cmd == "s")
            {
                break;
            }
        }

        Serial.print("模式 ");
        Serial.print(pattern % 6 + 1);
        Serial.print(": ");

        switch (pattern % 6)
        {
        case 0:
            Serial.println("短蜂鸣");
            shortBeep();
            break;
        case 1:
            Serial.println("长蜂鸣");
            longBeep();
            break;
        case 2:
            Serial.println("双音调");
            dualTone();
            break;
        case 3:
            Serial.println("警报声");
            alarmSound();
            break;
        case 4:
            Serial.println("上升音调");
            risingTone();
            break;
        case 5:
            Serial.println("下降音调");
            fallingTone();
            break;
        }

        pattern++;
        delay(2000);
    }

    stopBuzzer();
    Serial.println("✅ 连续测试已停止");
}

// ========== 音效函数 ==========
void playStartupSound()
{
    tone(BUZZER_PIN, NOTE_C4, 200);
    delay(250);
    tone(BUZZER_PIN, NOTE_E4, 200);
    delay(250);
    tone(BUZZER_PIN, NOTE_G4, 200);
    delay(250);
    tone(BUZZER_PIN, NOTE_C5, 400);
    delay(500);
}

void playHappyBirthday()
{
    int melody[] = {
        NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4,
        NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_G4, NOTE_F4,
        NOTE_C4, NOTE_C4, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_E4, NOTE_D4,
        NOTE_AS4, NOTE_AS4, NOTE_A4, NOTE_F4, NOTE_G4, NOTE_F4};

    int durations[] = {
        250, 250, 500, 500, 500, 1000,
        250, 250, 500, 500, 500, 1000,
        250, 250, 500, 500, 500, 500, 1000,
        250, 250, 500, 500, 500, 1000};

    int numNotes = sizeof(melody) / sizeof(melody[0]);

    for (int i = 0; i < numNotes; i++)
    {
        tone(BUZZER_PIN, melody[i], durations[i]);
        delay(durations[i] + 50);
    }
}

void playMarioTheme()
{
    int melody[] = {
        NOTE_E7, NOTE_E7, 0, NOTE_E7, 0, NOTE_C7, NOTE_E7, 0,
        NOTE_G7, 0, 0, 0, NOTE_G6, 0, 0, 0};

    int durations[] = {
        150, 150, 150, 150, 150, 150, 150, 150,
        150, 150, 150, 150, 150, 150, 150, 150};

    for (int i = 0; i < 16; i++)
    {
        if (melody[i] != 0)
        {
            tone(BUZZER_PIN, melody[i], durations[i]);
        }
        delay(durations[i] + 25);
    }
}

void playBeepPattern1()
{
    tone(BUZZER_PIN, NOTE_C5, 100);
    delay(150);
}

void playBeepPattern2()
{
    tone(BUZZER_PIN, NOTE_E5, 100);
    delay(120);
    tone(BUZZER_PIN, NOTE_G5, 100);
    delay(150);
}

void playBeepPattern3()
{
    tone(BUZZER_PIN, NOTE_G4, 200);
    delay(250);
    tone(BUZZER_PIN, NOTE_C5, 200);
    delay(250);
}

void playBeepPattern4()
{
    for (int i = 0; i < 3; i++)
    {
        tone(BUZZER_PIN, NOTE_A4, 50);
        delay(80);
    }
}

void shortBeep()
{
    tone(BUZZER_PIN, NOTE_C5, 100);
    delay(200);
}

void longBeep()
{
    tone(BUZZER_PIN, NOTE_C5, 500);
    delay(700);
}

void dualTone()
{
    tone(BUZZER_PIN, NOTE_C4, 200);
    delay(250);
    tone(BUZZER_PIN, NOTE_G4, 200);
    delay(250);
}

void alarmSound()
{
    for (int i = 0; i < 5; i++)
    {
        tone(BUZZER_PIN, NOTE_A5, 100);
        delay(120);
        tone(BUZZER_PIN, NOTE_E5, 100);
        delay(120);
    }
}

void risingTone()
{
    for (int freq = 200; freq <= 2000; freq += 100)
    {
        tone(BUZZER_PIN, freq, 50);
        delay(60);
    }
}

void fallingTone()
{
    for (int freq = 2000; freq >= 200; freq -= 100)
    {
        tone(BUZZER_PIN, freq, 50);
        delay(60);
    }
}

// ========== 工具函数 ==========
void stopBuzzer()
{
    noTone(BUZZER_PIN);
    digitalWrite(BUZZER_PIN, LOW);
}

void checkButton()
{
    // 按键检测逻辑 (如果需要)
}

void autoTest()
{
    testMode = (testMode + 1) % 6;

    Serial.println("\n🔄 自动测试模式 " + String(testMode + 1));

    switch (testMode)
    {
    case 0:
        shortBeep();
        break;
    case 1:
        dualTone();
        break;
    case 2:
        tone(BUZZER_PIN, NOTE_C5, 200);
        delay(300);
        break;
    case 3:
        risingTone();
        break;
    case 4:
        playBeepPattern2();
        break;
    case 5:
        tone(BUZZER_PIN, NOTE_G4, 300);
        delay(400);
        break;
    }
}

// ========== 程序结束 ==========